package p2pscrabble;

import java.io.File;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class LoginWindow extends JFrame {
	public final static int DISCONNECTED = 1;
	public final static int DISCONNECTING = 2;
	public final static int HOSTING = 3;
	public final static int CONNECTING = 4;
	public final static int CONNECTED = 5;
	public final static String END_CHAT_SESSION = new Character((char) 0)
			.toString();

	// settings for the connection
	private int connectionStatus = DISCONNECTED;
	private String serverIP = "localhost";
	private int portNum = 1234;
	//
	private ServerSocket server = null;
	private Socket socket = null;
	private Connection connection;

	private String myName;
	private boolean isHost;

	public LoginWindow(String myName, String serverIP, int portNum) {
		this.myName = myName;
		this.serverIP = serverIP;
		this.portNum = portNum;
		initComponent();
	}

	private void initComponent() {
		newGameButton = new JButton("New Game");
		joinGameButton = new JButton("Join Game");
		cancelButton = new JButton("Cancel");
		nameLabel = new JLabel("User name");
		ipLabel = new JLabel("IP");
		portLabel = new JLabel("Port number");
		fileLabel = new JLabel("Load file");
		nameField = new JTextField(myName, 20);
		ipField = new JTextField(serverIP, 20);
		portField = new JTextField(Integer.toString(portNum), 20);
		fileField = new JTextField("", 20);

		buttonPanel = new JPanel();
		fieldPanel = new JPanel();

		this.add(fieldPanel);

		javax.swing.GroupLayout fieldPanelLayout = new javax.swing.GroupLayout(
				fieldPanel);
		fieldPanel.setLayout(fieldPanelLayout);
		fieldPanelLayout
				.setHorizontalGroup(fieldPanelLayout
						.createParallelGroup(
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup(
								fieldPanelLayout
										.createSequentialGroup()
										.addContainerGap()
										.addGroup(
												fieldPanelLayout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.LEADING)
														.addComponent(nameLabel)
														.addComponent(ipLabel)
														.addComponent(portLabel)
														.addComponent(fileLabel))
										.addGap(24, 24, 24)
										.addGroup(
												fieldPanelLayout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.LEADING,
																false)
														.addComponent(nameField)
														.addComponent(ipField)
														.addComponent(
																portField,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																124,
																Short.MAX_VALUE)
														.addComponent(fileField))));
		fieldPanelLayout
				.setVerticalGroup(fieldPanelLayout
						.createParallelGroup(
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup(
								fieldPanelLayout
										.createSequentialGroup()
										.addGroup(
												fieldPanelLayout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.BASELINE)
														.addComponent(nameLabel)
														.addComponent(
																nameField,
																javax.swing.GroupLayout.PREFERRED_SIZE,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																javax.swing.GroupLayout.PREFERRED_SIZE))
										.addPreferredGap(
												javax.swing.LayoutStyle.ComponentPlacement.RELATED)
										.addGroup(
												fieldPanelLayout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.BASELINE)
														.addComponent(ipLabel)
														.addComponent(
																ipField,
																javax.swing.GroupLayout.PREFERRED_SIZE,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																javax.swing.GroupLayout.PREFERRED_SIZE))
										.addPreferredGap(
												javax.swing.LayoutStyle.ComponentPlacement.RELATED)
										.addGroup(
												fieldPanelLayout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.BASELINE)
														.addComponent(portLabel)
														.addComponent(portField))
										.addPreferredGap(
												javax.swing.LayoutStyle.ComponentPlacement.RELATED)
										.addGroup(
												fieldPanelLayout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.BASELINE)
														.addComponent(fileLabel)
														.addComponent(fileField))));

		javax.swing.GroupLayout buttonPanelLayout = new javax.swing.GroupLayout(
				buttonPanel);
		buttonPanel.setLayout(buttonPanelLayout);
		buttonPanelLayout
				.setHorizontalGroup(buttonPanelLayout
						.createParallelGroup(
								javax.swing.GroupLayout.Alignment.CENTER)
						.addGroup(
								buttonPanelLayout
										.createSequentialGroup()
										.addGroup(
												buttonPanelLayout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.CENTER)
														.addComponent(
																newGameButton)
														.addComponent(
																joinGameButton)
														.addComponent(
																cancelButton))
										.addContainerGap(24, Short.MAX_VALUE)));
		buttonPanelLayout
				.setVerticalGroup(buttonPanelLayout
						.createParallelGroup(
								javax.swing.GroupLayout.Alignment.CENTER)
						.addGroup(
								buttonPanelLayout
										.createSequentialGroup()
										.addGroup(
												buttonPanelLayout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.CENTER)
														.addComponent(
																newGameButton))
										.addPreferredGap(
												javax.swing.LayoutStyle.ComponentPlacement.RELATED)
										.addGroup(
												buttonPanelLayout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.CENTER)
														.addComponent(
																joinGameButton,
																javax.swing.GroupLayout.PREFERRED_SIZE,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																javax.swing.GroupLayout.PREFERRED_SIZE))
										.addPreferredGap(
												javax.swing.LayoutStyle.ComponentPlacement.RELATED)
										.addGroup(
												buttonPanelLayout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.CENTER)
														.addComponent(
																cancelButton,
																javax.swing.GroupLayout.PREFERRED_SIZE,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																javax.swing.GroupLayout.PREFERRED_SIZE))));

		javax.swing.GroupLayout layout = new javax.swing.GroupLayout(
				getContentPane());
		getContentPane().setLayout(layout);
		layout.setHorizontalGroup(layout.createParallelGroup(
				javax.swing.GroupLayout.Alignment.CENTER).addComponent(
				fieldPanel, javax.swing.GroupLayout.DEFAULT_SIZE,
				javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
				.addComponent(buttonPanel,
						javax.swing.GroupLayout.DEFAULT_SIZE,
						javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE));
		layout
				.setVerticalGroup(layout
						.createParallelGroup(
								javax.swing.GroupLayout.Alignment.CENTER)
						.addGroup(
								layout
										.createSequentialGroup()
										.addComponent(
												fieldPanel,
												javax.swing.GroupLayout.PREFERRED_SIZE,
												javax.swing.GroupLayout.DEFAULT_SIZE,
												javax.swing.GroupLayout.PREFERRED_SIZE)
										.addPreferredGap(
												javax.swing.LayoutStyle.ComponentPlacement.RELATED)
										.addComponent(
												buttonPanel,
												javax.swing.GroupLayout.PREFERRED_SIZE,
												352,
												javax.swing.GroupLayout.PREFERRED_SIZE)));

		newGameButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				new_game();
			}
		});

		joinGameButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				join_game();
			}
		});

		cancelButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				cancel();
			}
		});

		this.addWindowListener(new java.awt.event.WindowAdapter() {
			public void windowClosing(final java.awt.event.WindowEvent evt) {
				System.exit(0);
			}
		});

		setSize(400, 300);
		setResizable(false);
		setEnabled(true);
		java.awt.EventQueue.invokeLater(new Runnable() {
			@Override
			public void run() {
				setVisible(true);
			}
		});

	}

	private void new_game() {
		myName = nameField.getText();
		portNum = Integer.parseInt(portField.getText());

		changeStatus(HOSTING);
		try {
			server = new ServerSocket(portNum);
			server.setSoTimeout(5000);
			socket = server.accept();
			socket.setKeepAlive(true);
			server.close();
			changeStatus(CONNECTED);
		} catch (IOException ioe) {
			cleanUp();
			changeStatus(DISCONNECTED);
		}
		System.out.println(connectionStatus);
	}

	private void join_game() {
		myName = nameField.getText();
		serverIP = ipField.getText();
		portNum = Integer.parseInt(portField.getText());

		changeStatus(CONNECTING);

		try {
			socket = new Socket(serverIP, portNum);
			socket.setKeepAlive(true);
			changeStatus(CONNECTED);

		} catch (IOException ex) {
			// client cannot connect to the server
			cleanUp();
			changeStatus(DISCONNECTED);
		}

		System.out.println(connectionStatus);
	}

	private void cancel() {
		changeStatus(DISCONNECTED);
		cleanUp();
		System.out.println(connectionStatus);
	}

	private void changeStatus(int status) {
		connectionStatus = status;
		switch (connectionStatus) {
		case HOSTING:
			joinGameButton.setEnabled(false);
			newGameButton.setEnabled(false);
			ipField.setEditable(false);
			nameField.setEditable(false);
			portField.setEditable(false);
			isHost = true;
			break;
		case CONNECTING:
			joinGameButton.setEnabled(false);
			newGameButton.setEnabled(false);
			ipField.setEditable(false);
			nameField.setEditable(false);
			portField.setEditable(false);
			isHost = false;
			break;
		case CONNECTED:
			break;
		case DISCONNECTING:
			break;
		case DISCONNECTED:
			joinGameButton.setEnabled(true);
			newGameButton.setEnabled(true);
			ipField.setEditable(true);
			nameField.setEditable(true);
			portField.setEditable(true);
			isHost = false;
			break;
		}
	}

	private void cleanUp() {
		try {
			if (server != null) {
				server.close();
				server = null;
			}
		} catch (IOException e) {
			server = null;
		}

		try {
			if (socket != null) {
				socket.close();
				socket = null;
			}
		} catch (IOException e) {
			socket = null;
		}
	}

	public Connection getConnection() {
		connection = new Connection(socket);
		return connection;
	}

	public int getConnectionStatus() {
		return connectionStatus;
	}

	public String getMyName() {
		return myName;
	}

	public boolean isHost() {
		return isHost;
	}
	
	public String getFileName() {
		File f = new File (fileField.getText());
		if (f.exists()) {
			return fileField.getText();
		}
		else
			return "!@#$%";
	}

	private JButton newGameButton;
	private JButton joinGameButton;
	private JButton cancelButton;
	private JLabel nameLabel;
	private JLabel ipLabel;
	private JLabel portLabel;
	private JLabel fileLabel;
	private JPanel buttonPanel;
	private JPanel fieldPanel;
	private JTextField nameField;
	private JTextField ipField;
	private JTextField portField;
	private JTextField fileField;

}
